﻿//////#define _CRT_SECURE_NO_WARNINGS 1
//////#include "test.h"
////////class A
////////{
////////public:
////////	A(int a = 4)
////////		:_a1(0)
////////		,_a2(a)
////////	{}
////////private:
////////	int _a1 = 2;
////////	int _a2 = 2;
////////};
////////int main()
////////{
////////	A aa;
////////}
////////typedef int STDateType;
////////class Stack
////////{
////////public:
////////	Stack(int n)
////////	{
////////		STDateType* _arr = (STDateType*)malloc(sizeof(STDateType) * n);
////////		int _capacity = 0;
////////		int _top = 0;
////////	}
////////private:
////////	STDateType* _arr;
////////	int _capacity;
////////	int _top;
////////};
//////
////////class A
////////{
////////public:
////////	static int _scount;
////////
////////};
////////
////////int A::_scount = 0;
////////
////////int main()
////////{
////////	cout << sizeof(A) << endl;
////////	cout << sizeof(A::_scount) << endl;
////////	return 0;
////////}
//////
//////
//////
////////int GetMonthDay(int year, int month) {
////////    static int MonthDay[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
////////    if (month == 2 && (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)) {
////////        return 29;
////////    }
////////    return MonthDay[month];
////////}
////////
////////int main() {
////////    int year = 0, month = 0, day = 0;
////////    cin >> year >> month >> day;
////////    if (year > 2200 || year < 1900 || month>12 || month <= 0 || day > GetMonthDay(year, month) || day <= 0)
////////    {
////////        return 0;
////////    }
////////    int sum = 0;
////////    for (int i = 1; i < month; i++)
////////    {
////////        sum += GetMonthDay(year, i);
////////    }
////////    cout << (sum + day) << endl;
////////}
//////
//////
////////class Solution {
////////	// 内部类 
////////	class Sum
////////	{
////////	public:
////////		Sum()
////////		{
////////			_ret += _i;
////////			++_i;
////////		}
////////	};
////////	static int _i;
////////	static int _ret;
////////public:
////////	int Sum_Solution(int n) {
////////		// 变⻓数组 
////////		Sum arr[n];
////////		return _ret;
////////	}
////////};
////////int Solution::_i = 1;
////////int Solution::_ret = 0;
//////
////////int main()
////////{
////////	int i = 12;
////////	int j = 4;
////////	int k = i - j;
////////	cout << k << endl;
////////}
//////
//////
////////void Test()
////////{
////////	// 动态申请一个int类型的空间
////////	int* ptr4 = new int;
////////
////////	// 动态申请一个int类型的空间并初始化为10
////////	int* ptr5 = new int(10);
////////
////////	// 动态申请10个int类型的空间
////////	int* ptr6 = new int[3];
////////
////////	delete ptr4;
////////	delete ptr5;
////////	delete[] ptr6;
////////}
////////class A
////////{
////////public:
////////	A(int time, int day)
////////	{
////////		_time = time;
////////		_day = day;
////////	}
////////private:
////////	int _time;
////////	int _day;
////////};
////////int main()
////////{
////////	A* ptr = new A{ 1,2 };
////////}
//////
//////
////////class A
////////{
////////public:
////////	A(int a = 0)
////////		: _a(a)
////////	{
////////		cout << "A():" << this << endl;
////////	}
////////	~A()
////////	{
////////		cout << "~A():" << this << endl;
////////	}
////////private:
////////	int _a;
////////};
////////int main()
////////{
////////	// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间
////////	//还会调用构造函数和析构函数
////////		A* p1 = (A*)malloc(sizeof(A));
////////	A* p2 = new A(1);
////////	free(p1);
////////	delete p2;
////////	// 内置类型是几乎是一样的
////////	int* p3 = (int*)malloc(sizeof(int)); // C
////////	int* p4 = new int;
////////	free(p3);
////////	delete p4;
////////	A* p5 = (A*)malloc(sizeof(A) * 10);
////////	A* p6 = new A[10];
////////	free(p5);
////////	delete[] p6;
////////	return 0;
////////}
//////
////////void Swap(int& left, int& right)
////////{
////////	int temp = left;
////////	left = right;
////////	right = temp;
////////}
////////void Swap(double& left, double& right)
////////{
////////	double temp = left;
////////	left = right;
////////	right = temp;
////////}
////////void Swap(char& left, char& right)
////////{
////////	char temp = left;
////////	left = right;
////////	right = temp;
////////}
////////template<typename T>
////////void Swap(T& left, T& right)
////////{
////////	T temp = left;
////////	left = right;
////////	right = temp;
////////}
//////
////////template<class T>
////////T Add(const T& left, const T& right)
////////{
////////	return left + right;
////////}
////////int main()
////////{
////////	int a1 = 10, a2 = 20;
////////	double d1 = 10.0, d2 = 20.0;
////////	Add(a1, a2);
////////	Add(d1, d2);
////////	return 0;
////////}
////////int main(void)
////////{
////////	int a = 10;
////////	double b = 20.0;
////////
////////	// 显式实例化
////////	Add<int>(a, b);
////////	return 0;
////////}
//////// 专门处理int的加法函数
////////int Add(int left, int right)
////////{
////////	return left + right;
////////}
////////
////////// 通用加法函数
////////template<class T>
////////T Add(T left, T right)
////////{
////////	return left + right;
////////}
////////
////////void Test()
////////{
////////	Add(1, 2);    // 与非模板函数匹配，编译器不需要特化
////////	Add<int>(1, 2);     // 调用编译器特化的Add版本
////////}
//////
//////
////////// 专门处理int的加法函数
////////int Add(int left, int right)
////////{
////////	return left + right; 
////////}
////////
////////// 通用加法函数
////////template<class T1, class T2>
////////T1 Add(T1 left, T2 right)
////////{
////////	return left + right;
////////}
////////
////////void Test()
////////{
////////	Add(1, 2);     // 与非函数模板类型完全匹配，不需要函数模板实例化
////////	Add(1, 2.0);   // 模板函数可以生成更加匹配的版本，编译器根据实参生成更加匹配的Add函数
////////}
//////
////////class A
////////{
////////public:
////////	A(int a = 1)
////////	{
////////		_a = a;
////////	}
////////private:
////////	int _a;
////////};
////////
////////int main()
////////{
////////	A* ptr = (A*)operator new(sizeof(A));
////////	//A* ptr = (A*)malloc(sizeof(A));
////////	
////////	//进行初始化
////////
////////	ptr->~A();//析构函数可以显式调用，但是构造函数不可以，也就是说ptr->A()是错误的
////////}
//////
////////int main()
////////{
////////	int arr[3] = { 1,2,3 };
////////	for (int i = 0; i < 3; i++)
////////	{
////////		cout << arr[i] << " ";
////////	}
////////	cout << endl;
////////	for (int i = 0; i < 3; i++)
////////	{
////////		cout << arr[i] << " " << endl << endl;
////////	}
////////	return 0;
////////}
//////
////////int main()
////////{
////////	cout << i << endl;
////////	return 0;
////////}
//////
//////namespace bit
//////{
//////	const size_t string::npos = -1;
//////
//////	string::string(size_t n, char ch)
//////		:_str(new char[n + 1])
//////		, _size(n)
//////		, _capacity(n)
//////	{
//////		for (size_t i = 0; i < n; i++)
//////		{
//////			_str[i] = ch;
//////		}
//////
//////		_str[_size] = '\0';
//////	}
//////
//////	string::string(const char* str)
//////		:_size(strlen(str))
//////	{
//////		_capacity = _size;
//////		_str = new char[_size + 1];
//////		strcpy(_str, str);
//////	}
//////
//////	// s2(s1)
//////	string::string(const string& s)
//////	{
//////		_str = new char[s._capacity + 1];
//////		strcpy(_str, s._str);
//////		_size = s._size;
//////		_capacity = s._capacity;
//////	}
//////
//////
//////	void string::push_back(char ch)
//////	{
//////		if (_size + 1 > _capacity)
//////		{
//////			// 扩容
//////			reserve(_capacity == 0 ? 4 : _capacity * 2);
//////		}
//////
//////		_str[_size] = ch;
//////		++_size;
//////		_str[_size] = '\0';
//////	}
//////
//////	void string::append(const char* str)
//////	{
//////		size_t len = strlen(str);
//////		if (_size + len > _capacity)
//////		{
//////			// 扩容
//////			size_t newCapacity = 2 * _capacity;
//////			if (_size + len > 2 * _capacity)
//////			{
//////				newCapacity = _size + len;
//////			}
//////
//////			reserve(newCapacity);
//////		}
//////
//////		strcpy(_str + _size, str);
//////		_size += len;
//////	}
//////
//////	string& string::operator+=(char ch)
//////	{
//////		push_back(ch);
//////		return *this;
//////	}
//////
//////	string& string::operator+=(const char* str)
//////	{
//////		append(str);
//////		return *this;
//////	}
//////
//////	
//////	// s1 = s2
//////	// s1 = s1
//////	string& string::operator=(const string& s)
//////	{
//////		if (this != &s)
//////		{
//////			delete[] _str;
//////			_str = new char[s._capacity + 1];
//////			strcpy(_str, s._str);
//////			_size = s._size;
//////			_capacity = s._capacity;
//////		}
//////
//////		return *this;
//////	}
//////
//////	string::~string()
//////	{
//////		delete[] _str;
//////		_str = nullptr;
//////		_size = 0;
//////		_capacity = 0;
//////	}
//////
//////	void string::reserve(size_t n)
//////	{
//////		if (n > _capacity)
//////		{
//////			//cout << "reserve:" << n << endl;
//////			char* tmp = new char[n + 1];
//////			strcpy(tmp, _str);
//////			delete[] _str;
//////			_str = tmp;
//////			_capacity = n;
//////		}
//////	}
//////	ostream& operator<<(ostream& out, const string& s)
//////	{
//////		for (auto ch : s)
//////		{
//////			out << ch;
//////		}
//////
//////		return out;
//////	}
//////
//////	string string::substr(size_t pos, size_t len)
//////	{
//////		size_t leftlen = _size - pos;
//////		if (len > leftlen)
//////			len = leftlen;
//////
//////		string tmp;
//////		tmp.reserve(len);
//////		for (size_t i = 0; i < len; i++)
//////		{
//////			tmp += _str[pos + i];
//////		}
//////		return tmp;
//////	}
//////	void test_string1()
//////	{
//////		string s1("hello world");
//////		string s2(s1);
//////		cout << s2 << endl;
//////		for (auto ch : s1)
//////		{
//////			cout << ch;
//////		}
//////	}
//////	void test_string2()
//////	{
//////		/*string s1("hello world");
//////		cout << s1.substr(9) << endl;*/
//////		string s1("hello world");
//////
//////	}
//////}
//////
//////int main()
//////{
//////	//bit::test_string2();
//////	/*char arr[] = { 'a','b','v', '\0', 'a'};
//////	for (int i = 0; i < 5; i++)
//////	{
//////		cout << arr[i] << endl;
//////	}
//////	return 0;*/
//////	char arr[10];
//////	for (int i = 0; i < 10; i++)
//////	{
//////		arr[i] = 'a';
//////	}
//////	cout << arr << endl;
//////}
////
////
////
////#include <iostream>
////using namespace std;
////
////namespace xiaolong
////{
////    
////	//template<class A>
////	class Date
////	{
////		friend ostream& operator<<(ostream& _cout, const Date& d);
////	public:
////		Date(int year = 1900, int month = 1, int day = 1)
////			: _year(year)
////			, _month(month)
////			, _day(day)
////		{
////		}
////
////		bool operator<(const Date& d)const
////		{
////			return (_year < d._year) ||
////				(_year == d._year && _month < d._month) ||
////				(_year == d._year && _month == d._month && _day < d._day);
////		}
////
////		bool operator>(const Date& d)const
////		{
////			return (_year > d._year) ||
////				(_year == d._year && _month > d._month) ||
////				(_year == d._year && _month == d._month && _day > d._day);
////		}
////
////		//private:
////		int _year;
////		int _month;
////		int _day;
////	};
////
////
////	/*template<class T>
////	bool Less(T a, T b)
////	{
////		return  a < b;
////	}*/
////	
////
////	//template<>//函数模板特化
////	//bool Less<Date*>(Date* a, Date* b)
////	//{
////	//	return *a < *b;
////	//}
////
////	/*bool Less(Date* a, Date* b)
////	{
////		return *a < *b;
////	}*/
////
////	//template<class T>
////	//bool Less(const T& a, const T& b)//当参数为const引用类型时一定注意const修饰的是谁
////	//{
////	//	return  a < b;
////	//}
////
////	//template<>
////	//bool Less<Date*>(Date* const& a, Date* const& b)
////	//{
////	//	return *a < *b;
////	//}
////
////	//void test1()
////	//{
////	//	Date d1(1990, 3, 20);
////	//	Date d2(1991, 2, 14);
////	//	cout << Less(d1, d2) << endl;//结果是正确的
////
////	//	cout << Less(new Date(1990, 3, 20), new Date(1991, 2, 14)) << endl;//结果是随机的
////	//}
////	/*template<class T1, class T2>
////	class Data
////	{
////	public:
////		Data() { cout << "Data<T1, T2>" << endl; }
////	private:
////		T1 _d1;
////		T2 _d2;
////	};
////
////	template<>
////	class Data<int, char>
////	{
////	public:
////		Data() { cout << "data<int, char>" << endl; }
////	private:
////		int _d1;
////		char _d2;
////	};
////	void TestVector()
////	{
////		Data<int, int> d1;
////		Data<int, char> d2;
////	}*/
////
////	template<class T1, class T2>
////	class Data
////	{
////	public:
////		Data() { cout << "Data<T1, T2>" << endl; }
////	private:
////		T1 _d1;
////		T2 _d2;
////	};
////
////	/*template<class T1>
////	class Data<T1, int>
////	{
////	public:
////		Data() { cout << "Data<T1, int>" << endl; }
////	private:
////		T1 _d1;
////		int _d2;
////	};*/
////	template<class T2>//这里是你想让哪个参数不变，你就在括号写哪个，
////	                  //比如你想让上面模板中第二个参数不变，你就可以写T2，但是写T1也没问题
////	class Data<int, T2>//因为这里会确定你具体是哪个参数没变，但是建议按照原模板顺序，容易看
////	{
////	public:
////		Data() { cout << "Data<int, T1>" << endl; }
////	private:
////		int _d1;
////		T2 _d2;
////	};
////	void test2()
////	{
////		Data<char, char> d1;
////		Data<int, char> d2;//这里会优先调用特化模板
////	}
////
////
////}
////
////int main()
////{
////	//xiaolong::test1();
////	xiaolong::test2();
////	return 0;
////}
//
////#include <iostream>
////#include <vector>
////using namespace std;
//
////namespace xiaolong
////{
//	//class Student
//	//{
//	//public:
//	//	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证 
//	//	void identity()
//	//	{
//	//		// ...
//	//	}
//	//	// 学习 
//	//	void study()
//	//	{
//	//		// ...
//	//	}
//	//protected:
//	//	string _name = "peter"; // 姓名 
//	//	string _address; // 地址 
//	//	string _tel; // 电话 
//	//	int _age = 18; // 年龄 
//	//	int _stuid; // 学号 
//	//};
//	//class Teacher
//	//{
//	//public:
//	//	
//	//	//进⼊校园/图书馆/实验室刷⼆维码等⾝份认证 
//	//	void identity()
//	//	{
//	//		// ...
//	//	}
//	//	// 授课 
//	//	void teaching()
//	//	{
//	//		//...
//	//	}
//	//protected:
//	//	string _name = "张三"; // 姓名 
//	//	int _age = 18; // 年龄 
//	//	string _address; // 地址 
//	//	string _tel; // 电话 
//	//	string _title; // 职称 
//	//};
//	//class Person
//	//{
//	//public:
//	//	// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证 
//	//	void identity()
//	//	{
//	//		cout << "void identity()" << _name << endl;
//	//	}
//	//protected:
//	//	string _name = "张三"; // 姓名 
//	//	string _address; // 地址 
//	//	string _tel; // 电话 
//	//	int _age = 18; // 年龄 
//	//};
//	//class Student : public Person
//	//{
//	//public:
//	//	// 学习 
//	//	void study()
//	//	{
//	//		// ...
//	//	}
//	//protected:
//	//	int _stuid; // 学号 
//	//};
//	//class Teacher : public Person
//	//{
//	//public:
//	//	// 授课 
//	//	void teaching()
//	//	{
//	//		//...
//	//	}
//	//protected:
//	//	string title; // 职称 
//	//};
//
//	
//	
////	template<class T>
////	class stack : public std::vector<T>
////	{
////	public:
////		void push(const T& x)
////		{
////			// 基类是类模板时，需要指定⼀下类域， 
////			// 否则编译报错:error C3861: “push_back”: 找不到标识符 
////			// 因为stack<int>实例化时，也实例化vector<int>了 
////			// 但是模版是按需实例化，push_back等成员函数未实例化，所以找不到 
////			vector<T>::push_back(x);
////			//push_back(x);//编译报错
////		}
////		void pop()
////		{
////			vector<T>::pop_back();
////		}
////		const T& top()
////		{
////			return vector<T>::back();
////		}
////		bool empty()
////		{
////			return vector<T>::empty();
////		}
////	};
////
////}
//
////class Person
////{
////protected:
////	string _name; // 姓名 
////	string _sex; // 性别 
////	int _age; // 年龄 
////};
////class Student : public Person
////{
////public:
////	int _No; // 学号 
////};
//
//
////class Person
////{
////public:
////	Person(const char* name = "peter")
////		: _name(name)
////	{
////		cout << "Person()" << endl;
////	}
////
////	Person(const Person& p)
////		: _name(p._name)
////	{
////		cout << "Person(const Person& p)" << endl;
////	}
////
////	Person& operator=(const Person& p)
////	{
////		cout << "Person operator=(const Person& p)" << endl;
////		if (this != &p)
////			_name = p._name;
////
////		return *this;
////	}
////
////	~Person()
////	{
////		cout << "~Person()" << endl;
////	}
////protected:
////	string _name; // 姓名 
////};
////class Student : public Person
////{
////public:
////	Student(const char* name, int num)
////		:Person(name)
////		, _num(num)
////	{ }
////	Student(const Student& st)
////		:Person(st)
////		,_num(st._num)
////	{ }
////
////	Student& operator=(const Student& st)
////	{
////		if (this != &st)
////		{
////			Person::operator=(st);
////			_num = st._num;
////		}
////		return *this;
////	}
////	void Print()
////	{
////		cout << _name << ' ' << _num << endl;
////	}
////
////protected:
////	int _num; //学号 
////};
//
//
////class Father
////{
////public:
////	static int _num;
////	int _sex = '男';
////};
////int Father::_num = 10;
////
////class Son : public Father
////{
////public:
////	int _aaa = 0;
////};
////
////int main()
////{
////	Father f;
////	Son s;
////	cout << &f._num << endl;
////	cout << &f._num << endl;
////
////	cout << &f._sex << endl;
////	cout << &s._sex << endl;
////	//Student st("王强", 12);
////	////Student st1(st);
////	////st.Print();
////	//Student st1 = st;
////
////	//st1.Print();
////	return 0;
////}
////int main()
////{
////	/*xiaolong::stack<int> st;
////	st.push(1);
////	st.push(2);
////	st.push(3);*/
////	
////	/*Student st;
////	Person* p1 = &st;
////	Person& p2 = st;
////	Person p3 = st;*/
////
////	return 0;
////}
//
//
////#include <iostream>
////using namespace std;
////
////class Person
////{
////public:
////	virtual void BuyTicket()
////	{
////		cout << "全价" << endl;
////	}
////};
////
////class Student : public Person
////{
////public:
////	virtual void BuyTicket()
////	{
////		cout << "半价" << endl;
////	}
////};
////
////void test(Person& per)
////{
////	per.BuyTicket();
////}
//
////class Person {
////public:
////	virtual A* BuyTicket()
////	{
////		cout << "买票-全价" << endl;
////		return nullptr;
////	}
////};
////class Student : public Person {
////public:
////	virtual B* BuyTicket()
////	{
////		cout << "买票-打折" << endl;
////		return nullptr;
////	}
////};
//
//#include <iostream>
//using namespace std;
////class Car
////{
////public:
////	virtual void Drive()
////	{ }
////};
////
////class Benz : public Car
////{
////public:
////	virtual void Drive() override
////	{
////		cout << "111" << endl;
////	}
////};
//
////class Car
////{
////public:
////	virtual void Drive() final
////	{ }
////};
////class Car
////{
////public:
////	virtual void Drive() = 0;
////};
////	
////class Benz : public Car
////{
////public:
////	virtual void Drive()
////	{
////		cout << "Benz-舒适" << endl;
////	}
////};
////class BMW : public Car
////{
////public:
////	virtual void Drive()
////	{
////		cout << "BMW-操控" << endl;
////	}
////};
//
////class Base
////{
////public:
////	virtual void Func1()
////	{
////		cout << "Func1()" << endl;
////	}
////protected:
////	int _b = 1;
////	char _ch = 'x';
////};
////int main()
////{
////	Base b;
////	cout << sizeof(b) << endl;
////	return 0;
////}
////int main()
////{
////	//Person p;
////	//Student s;
////	//test(p);
////	//test(s);
////
////	return 0;
////}
//
//class A
//{
//public:
//	 virtual ~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//
//class B : public A {
//public:
//	~B()
//	{
//		cout << "~B()->delete:" << _p << endl;
//		delete _p;
//	}
//protected:
//	int* _p = new int[10];
//};
//
//void func(A* ptr)
//{
//	delete ptr;
//	// 两个析构函数调用后都等隐式转换为ptr->destructor()，构成了多态
//}
//
//int main()
//{
//	func(new A);
//	func(new B);
//	return 0;
//}

//#include <iostream>
//using namespace std;
//
//int main()
//{
//	cout << "周宇轩施主" << endl;
//	return 0;
//}


//struct Point
//{
//	int _x;
//	int _y;
//};
//int main()
//{
//	int array1[] = { 1, 2, 3, 4, 5 };
//	int array2[5] = { 0 };
//	Point p = { 1, 2 };
//
//	return 0;
//}

//#include<iostream>
//#include<vector>
//using namespace std;
//struct Point
//{
//	int _x;
//	int _y;
//};
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{
//		cout << "Date(int year, int month, int day)" << endl;
//	}
//	Date(const Date& d)
//		:_year(d._year)
//		, _month(d._month)
//		, _day(d._day)
//	{
//		cout << "Date(const Date& d)" << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//int main()
//{
//	// 内置类型⽀持列表初始化
//	int x1 = { 2 };
//	// ⾃定义类型⽀持列表初始化
//	Date d1 = { 2025, 1, 1 };
//	// 这⾥d2引⽤的是{ 2024, 7, 25 }构造的临时对象，如果不加const不能引用临时变量
//	const Date& d2 = { 2024, 7, 25 };
//
//	// Date d8 2025;//C++不支持这种写法，但是在C++98中如果结构体构造函数是单参数，可以Date d8 = 2025（不能省略大括号）
//
//	
//	// 左值：可以取地址 
//	// 以下的p、b、c、*p、s、s[0]就是常⻅的左值 
//	int* p = new int(0);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("111111");
//	s[0] = 'x';
//
//
//	// 右值：不能取地址 
//	double x = 1.1, y = 2.2;
//	// 以下⼏个10、x + y、fmin(x, y)、string("11111")都是常⻅的右值 
//	10;
//	x + y;
//	fmin(x, y);
//	string("11111");
//
//}

//#include <iostream>
//
//using namespace std;
//
//string Myclass(string x)
//{
//	return x;
//};
//
//int main()
//{
//	string x;
//	Myclass(move(x));
//	return 0;
//}

//// 由于引⽤折叠限定，f1实例化以后总是⼀个左值引⽤ 
//template<class T>
//void f1(T& x)
//{
//}
//// 由于引⽤折叠限定，f2实例化后可以是左值引⽤，也可以是右值引⽤ 
//template<class T>
//void f2(T&& x)
//{
//}
//int main()
//{
//	int n = 0;
//	// 没有折叠->实例化为void f1(int& x) 
//	f1<int>(n);
//	//f1<int>(0); // 报错,实例化为void f1(int& x) ，但是传了右值
//	
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	//f1<int&>(0); // 报错 
//	
//	// 折叠->实例化为void f1(int& x) 
//	f1<int&&>(n);
//	//f1<int&&>(0); // 报错, 实例化为void f1(int& x) ,但是传了右值
//	
//	// 折叠->实例化为void f1(const int& x) 
//	f1<const int&>(n);
//	f1<const int&>(0);
//	
//	// 折叠->实例化为void f1(const int& x) 
//	f1<const int&&>(n);
//	f1<const int&&>(0);
//	
//	// 没有折叠->实例化为void f2(int&& x) 
//	//f2<int>(n); // 报错 
//	f2<int>(0);
//	
//	// 折叠->实例化为void f2(int& x) 
//	f2<int&>(n);
//	//f2<int&>(0); // 报错 
//	
//	// 折叠->实例化为void f2(int&& x) 
//	//f2<int&&>(n); // 报错 
//	f2<int&&>(0);
//	return 0;
//}


//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	//x++;
//	cout << &a << endl;
//	cout << &x << endl << endl;
//}
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t) 
//	Function(10); // 右值 
//	int a;
//	
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t) 
//	Function(a); // 左值 
//	
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t) 
//	Function(std::move(a)); // 右值 
//	const int b = 8;
//	
//	// a是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int& t)
//	// 所以Function内部会编译报错，x不能++ 
//	Function(b); // const 左值 
//	
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&& t)
//	// 所以Function内部会编译报错，x不能++ 
//	Function(std::move(b)); // const 右值 
//	return 0;
//}

//void Fun(int& x) { cout << "左值引⽤" << endl; }
//void Fun(int&& x) { cout << "右值引⽤" << endl; }
//
//template<class T>
//void Function(T&& t)
//{
//	Fun(t);
//	//Fun(forward<T>(t));
//}
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t) 
//	Function(10); // 右值 
//	int a;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t) 
//	Function(a);
//}

#include <iostream>
#include <functional>
using namespace std;
//int f(int a, int b)
//{
//	return a + b;
//}
//struct Functor
//{
//public:
//	size_t operator() (int a, int b, int c)
//	{
//		return (size_t)(a + b + c);
//	}
//};

//class Plus
//{
//public:
//	Plus(int n = 10)
//		:_n(n)
//	{ }
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//	double plusd(double a, double b)
//	{
//		return (a + b) * _n;
//	}
//	double plust(double a, double b) const
//	{
//		return (a + b) * _n;
//	}
//private:
//	int _n;
//};
//
//int main()
//{
//	function<double(Plus*, double, double)> f1 = &Plus::plusd;//第一个参数this指针
//	Plus pa;
//	cout << f1(&pa, 3.2, 3.3) << endl;
//
//	function<double(Plus, double, double)> f2 = &Plus::plusd;//第一个参数可以传对象
//	Plus pb;
//	cout << f2(pb, 4.3, 5.4) << endl;
//
//	function<double(Plus&, double, double)> f3 = &Plus::plusd;//第一个对象可以传对象的引用
//	Plus pc;
//	cout << f3(pc, 4.3, 5.4) << endl;
//
//	function<double(const Plus&, double, double)> f4 = &Plus::plust;
//	Plus pd;  
//	cout << f4(pd, 4.3, 5.4) << endl;
//	//但是不能传const对象，因为this指针为const类型的话就是const成员函数了，要单独有一个const版本的成员函数
//
//	function<int(int, int)> f = &Plus::plusi;
//	cout << f(3, 2) << endl;
//
//}

//int main()
//{
//	function<int(int, int)> f1 = f;//必须要用等号赋值，而不是括号，因为这里的本质是对象给对象赋值
//	function<size_t(int, int, int)> f2 = Functor();
//	function<double(double, double)> f3 = [](double a, double b) { return a + b; };
// 	
//	cout << f1(3, 4) << endl;
//	cout << f2(2, 4, 5) << endl;
//	cout << f3(2.3, 4.5) << endl;
//}

//可以直接展开命名空间 using namespace placeholders，但是这里我们只用三个参数做演示，就不全展开了
using placeholders::_1;
using placeholders::_2;
using placeholders::_3;

//int Sub(int a, int b)
//{
//	return (a - b) * 10;
//}
//int SubX(int a, int b, int c)
//{
//	return (a - b - c) * 10;
//}

//int SubX(int a, int b, int c)
//{
//	return (a - b - c) * 10;
//}
//
//int main()
//{
//	auto b = bind(SubX, _2, 10, _1);
//	cout << b(5, 35) << endl;
//}

//int main()
//{
//	cout << Sub(10, 5) << endl;
//
//	auto b1 = bind(Sub, _2, _1);
//	cout << b1(10, 5) << endl;
//    
//	cout << SubX(10, 2, 3) << endl;
//
//	auto b2 = bind(SubX, _2, _3, _1);
//	cout << b2(10, 2, 3) << endl;
//	return 0;
//}

class Plus
{
public:
	double plusd(double a, double b)
	{
		return a + b;
	}
};

int main()
{
	//和function一样，成员函数指明类域并加上&
	function<double(double, double)> f = bind(&Plus::plusd, Plus(), _1, _2);
	cout << f(1.1, 1.1) << endl;
}